//----------------------------------------------------------------------------
// M A R I T I M E  R E S E A R C H  I N S T I T U T E  N E T H E R L A N D S
//----------------------------------------------------------------------------
// Copyright (C) 2008 - MARIN - All rights reserved - http://www.marin.nl
//----------------------------------------------------------------------------
// Program    : mermaid
// Module     : vbm
// File       : SolverFactory.cpp
//----------------------------------------------------------------------------

#include <string.h>
#include <map>
#include "SolverFactory.h"

// all known solvers:
#include "RrbSolver.h"
//#include "Cg4Solver.h"
#ifndef _WINDOWS
//#include "IterCudaSolver.h"
//#include "CudaRrbSolver.h"
#endif
#include "assertplus.h"

typedef Solver* (*NewSolver)(Array2D<REAL>*, Array2D<REAL>*, Array2D<REAL>*,
        int, int, REAL);

static std::map<std::string, NewSolver> solvercreator;

static void makeSolverList()
{
    if (!solvercreator.empty())
    {
        return;
    }
    solvercreator["rrb"] = NewRrbSolver;
   // solvercreator["cudarrb"] = NewCudaRrbSolver;
//    solvercreator["itercuda"] = NewIterCudaSolver;
   // solvercreator["cg4"] = NewCg4Solver;
}

/// creates a solver based upon its name

Solver* SolverFactory::create(const char *name, ///< solver name
        Array2D<REAL> *pmatC, ///< central matrix
        Array2D<REAL> *pmatS, ///< south matrix
        Array2D<REAL> *pmatW, ///< west matrix
        int N, ///< width
        int M, ///< height
        REAL tolerance) ///< solver tolerance
{
    makeSolverList();
    if (solvercreator.count(name))
    {
        printf("Solver created: %s\n", name);
        return solvercreator[name](pmatC, pmatS, pmatW, N, M, tolerance);
    }
    else
    {
        fprintf(stderr, "Unknown solver %s\n", name);
        return NULL;
    }
}

std::string SolverFactory::getSolvers()
{
    makeSolverList();
    std::string solvers;
    for (std::map<std::string, NewSolver>::const_iterator it = solvercreator.begin();
            it != solvercreator.end(); ++it)
    {
        solvers += it->first + " ";
    }
    return solvers;
}


